package com.bro.person.base.service.impl;

import com.bro.person.base.dao.mapper.IBroBaseMapper;
import com.bro.person.base.model.paging.PagingResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.List;

/**
 * @author jdd
 */
public abstract class BroBaseServiceImpl<T extends Serializable, TCriteria extends Serializable,ID extends Serializable>{

    private static Logger logger = LoggerFactory.getLogger(BroBaseServiceImpl.class);

    protected abstract IBroBaseMapper<T,TCriteria,ID> getBaseMapper();

    /**
     * 保存
     * @param entity
     * @return
     */
    public int save(T entity) {
        logger.debug("["+this.getClass().getName()+"][save]entering, entity:{}", entity);
        return getBaseMapper().insertSelective(entity);
    }


    /**
     * 保存并返回实体对象
     * 通常在rpc（对象序列化）后，实体对象的变更无法传递回调用方时使用
     * @param entity
     * @return
     */
    public T saveAndReturn(T entity){
        logger.debug("["+this.getClass().getName()+"][saveAndReturn]entering, entity:{}", entity);
        T result = null;
        int operateResult = getBaseMapper().insertSelective(entity);
        if(operateResult>0){
            result = entity;
        }
        return result;
    }


    /**
     * 主键更新
     * @param entity
     * @return
     */
    public int updateById(T entity) {
        logger.debug("["+this.getClass().getName()+"][updateById]entering, entity:{}", entity);
        return getBaseMapper().updateByPrimaryKeySelective(entity);
    }

    /**
     * 条件更新
     * @param entity
     * @param tCriteria
     * @return
     */
    public int updateByCriteria(T entity, TCriteria tCriteria) {
        logger.debug("["+this.getClass().getName()+"][updateByCriteria]entering, entity:{}, tCriteria:{}", entity, tCriteria);
        return getBaseMapper().updateByExampleSelective(entity,tCriteria);
    }

    /**
     * 按id删除
     * @param id
     * @return
     */
    public int deleteById(ID id) {
        logger.debug("["+this.getClass().getName()+"][deleteById]entering, id:{}", id);
        return getBaseMapper().deleteByPrimaryKey(id);
    }

    /**
     * 按条件删除
     * @param tCriteria
     * @return
     */
    public int deleteByCriteria(TCriteria tCriteria) {
        logger.debug("["+this.getClass().getName()+"][deleteByCriteria]entering, tCriteria:{}", tCriteria);
        return getBaseMapper().deleteByExample(tCriteria);
    }

    /**
     * 按id加载
     * @param id
     * @return
     */
    public T loadById(ID id) {
        logger.debug("["+this.getClass().getName()+"][loadById]entering, id:{}", id);
        return getBaseMapper().selectByPrimaryKey(id);
    }

    /**
     * 按条件查询
     *
     * @param tCriteria
     * @return
     */
    public List<T> queryByCriteria(TCriteria tCriteria) {
        logger.debug("["+this.getClass().getName()+"][queryByCriteria]entering, tCriteria:{}", tCriteria);
        return getBaseMapper().selectByExample(tCriteria);
    }

    /**
     * 查询所有
     * 注意效率问题
     * @return
     */
    public List<T> queryAll() {
        logger.debug("["+this.getClass().getName()+"][queryAll]entering");
        return queryAll(null);
    }

    /**
     * 查询所有（支持排序）
     * 注意效率问题
     * @param orderByClause
     * @return
     */
    public abstract List<T> queryAll(String orderByClause);

    /**
     * 按条件count
     * @param tCriteria
     * @return
     */
    public int countByCriteria(TCriteria tCriteria) {
        logger.debug("["+this.getClass().getName()+"][countByCriteria]entering, tCriteria:{}", tCriteria);
        int result = getBaseMapper().countByExample(tCriteria).intValue();
        logger.info("["+this.getClass().getName()+"][countByCriteria]result:{}, tCriteria:{}", result, tCriteria);
        return result;
    }

    public abstract PagingResult<T> pagingByCriteria(int pageNo, int pageSize, TCriteria tCriteria, T entity);

    /**
     * 瀑布流查询
     * @param pageSize
     * @param tCriteria
     * @return
     */
    public abstract List<T> fallloadByCriteria(int pageSize, TCriteria tCriteria);

    /**
     * 批量插入
     *
     * @param list
     * @return
     */
    public int insertBatchSelective(List<T> list){
        logger.debug("["+this.getClass().getName()+"][insertBatchSelective]entering, list:{}", list);
        int result = getBaseMapper().insertBatchSelective(list);
        logger.info("["+this.getClass().getName()+"][insertBatchSelective]result:{}, list:{}", result, list);
        return result;
    }

    /**
     * 批量更新
     *
     * @param list
     * @return
     */
    public int updateBatchByPrimaryKeySelective(List<T> list){
        logger.debug("["+this.getClass().getName()+"][updateBatchByPrimaryKeySelective]entering, list:{}", list);
        int result = getBaseMapper().updateBatchByPrimaryKeySelective(list);
        logger.info("["+this.getClass().getName()+"][updateBatchByPrimaryKeySelective]result:{}, list:{}", result, list);
        return result;
    }

}
